package ru.ifmo.croak.impl.ui.query.team1.stub;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.ifmo.croak.api.*;
import ru.ifmo.croak.util.CroakFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


public class QueryUI implements Runnable {
    private static final Logger log = LoggerFactory.getLogger(QueryUI.class);

    class QueryFrame extends JFrame {
        JTextField author;
        JTextField text;
        JTextField limit;
        JButton submit;

        public QueryFrame() {
            super("Enter you query!");
            setLayout(new GridLayout(4, 1));
            author = new JTextField();
            add(author);
            text = new JTextField();
            add(text);
            limit = new JTextField("10");
            add(limit);
            submit = new JButton("Sign up!");
            submit.addActionListener(new QuerySubmitListener());
            add(submit);
            setSize(300, 200);
            setVisible(true);
        }

        private class QuerySubmitListener implements ActionListener {
            public void actionPerformed(ActionEvent actionEvent) {
                QueryRequest request = new QueryRequest();
                if (!author.getText().isEmpty()) {
                    request.setAuthor(author.getText());
                }
                if (!text.getText().isEmpty()) {
                    request.setText(text.getText());
                }
                request.setLimit(Integer.parseInt(limit.getText()));
                MessageQuery query = queryService.createQuery(request);
                messaging.addMessageQuery(query);
            }
        }
    }

    class ResponseFrame extends JFrame {
        JTextArea area;

        public ResponseFrame() {
            super("Read the news!");
            setLayout(new GridLayout(1, 1));
            area = new JTextArea();
            area.setEditable(false);
            add(area);
            setSize(300, 200);
            setVisible(true);
        }
    }

    class Messaging implements MessageListener {

        Messaging(JTextArea output) {
            map = new ConcurrentHashMap<UUID, Message>();
            this.output = output;
        }

        JTextArea output;
        ConcurrentHashMap<UUID, Message> map;

        public void addMessageQuery(MessageQuery query) {
            query.setMessageListener(this);
            final List<Message> messages = query.getMessages();
            log.trace("Got {} messages", messages.size());
            log.debug("Querying messages: {}", messages);
            for (Message message : messages) {
                processMessage(message);
            }
        }

        private void processMessage(Message message) {
            log.debug("processMessage {}", message);
            if (map.putIfAbsent(message.getId(), message) == null) {
                log.info("showMessage {}", message);
                output.setText(message + "\n" + output.getText());
            }
            log.info("procesedMessage {}", message);
        }

        public void messageAvailable(Message message) {
            processMessage(message);
        }
    }

    private Messaging messaging;
    private final QueryService queryService;

    public QueryUI(String name) {
        String queryProviderName = CroakFactory.getInstance().getProperty(name + ".provider");
        queryService = CroakFactory.getInstance().getImplementation(QueryService.class, queryProviderName);
    }

    ResponseFrame rf;
    QueryFrame qf;

    public void run() {
        rf = new ResponseFrame();
        messaging = new Messaging(rf.area);
        qf = new QueryFrame();
    }
}